// ExpProbInterface.C

#include <iostream>
#include <fstream>
#include <string.h>

#include "ExpProbInterface.H"

ExpProbInterface::ExpProbInterface(ExpWaveProb &prob, char *contparam)
  : contParam(contparam),
    prevEval(EVALINIT),
    prevEval2(EVALINIT),
    prevEval0(EVALINIT),
    flag0(0),
    flag1(0),
    flag2(0),
    problem(prob)
{ 
}

ExpProbInterface::~ExpProbInterface()
{ }

void ExpProbInterface::printSolution(const::Epetra_Vector &x, double paramVal)
{
  cerr << contParam << " = " << paramVal << endl;

  int m = problem.getM();
  int n = problem.getN();
  int dim = m * n;
  double p0 = problem.getP0();
  double q = problem.getQ();
  double a = problem.getA();
  double b = problem.getB();

  double avg = 0.0;
  for (int i=0; i<m; ++i)
    avg += x[i];
  avg /= m;

  double d = 0.0;
  for (int i=0; i<m; ++i)
    d += (avg - x[i])*(avg - x[i]);

  cerr << "  sigma = " << sqrt(d/n) << endl;


  char filename[32];
  sprintf(filename, "sol.%s%.4f", contParam, paramVal);
  ofstream fout(filename, ios::trunc);
  fout.precision(15);
  fout << "exp" << endl
       << m << endl
       << n << endl
       << p0 << endl
       << q << endl
       << a << endl
       << b << endl << endl;
  for (int i=0; i<dim; ++i)
    fout << x[i] << endl;
  fout.close();
}

bool ExpProbInterface::computeF(const Epetra_Vector& x, Epetra_Vector& F, FillType ft)
{
  return problem.computeF(x, F);
}

bool ExpProbInterface::computeJacobian(const Epetra_Vector& x, Epetra_Operator& Jac)
{
  return problem.computeJacobian(x);
}

void ExpProbInterface::setParameters(const LOCA::ParameterVector& params)
{
  char label[2];
  double value;
  for (int i=0; i<params.length(); ++i)
  {
    sprintf(label, "%s", params.getLabel(i).c_str());
    value = params.getValue(i);
    if (strcmp(label, "Q") == 0)
      problem.setQ(value);
    else if (strcmp(label, "A") == 0)
      problem.setA(value);
    else if (strcmp(label, "B") == 0)
      problem.setB(value);
    else {
      cout << "Unknown parameter " << label << " #" << i << endl;
      exit(1);
    }
  }
}

